<?php
/**
* <b>GetFilter</b>
* 
* A memory efficient version of GetList indended to specify the order of  
* attributes in a return, limit which attributes are returned, and/or 
* to return only attribute values. 
* 
* Use the SetFilter plugin to specify returned attributes and format.
* 
* NOTE: This function's arguments behave in the same manner as GetList(...)
*
* TODO: unit tests, usage
* 
* @author Brice Burgess <bhb@iceburg.net>
* @version 0.2
* @copyright Free for personal & commercial use. (Offered under the BSD license)
*
* @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...} 
* @param string $sortBy 
* @param boolean $ascending 
* @param int limit 
* @return string $json
*/
class GetFilter
{
	private $sourceObject;
	private $argv;
	public $version = '0.1';

	function Version()
	{
		return $this->version;
	}

	function GetFilter($sourceObject,$argv)
	{
		$this->sourceObject = $sourceObject;
		$this->argv = $argv;
	}

	
	function Execute()
	{
		// set defaults -- override with SetFilter()
		$attributes = (isset($this->sourceObject->_filter)) ?
			$this->sourceObject->_filter['attributes'] :
			array();
		$keyValue = (isset($this->sourceObject->_filter)) ?
			$this->sourceObject->_filter['keyValue'] :
			true;
		
		// bb
		/**
		 * Mimick POG's GetList() w/ slight modifications (marked "//bb")
		 * Runs a manual DB query for performance sake!!!
		 */
		
		$fcv_array = isset($this->argv[0]) ? $this->argv[0] : array();
		$sortBy = isset($this->argv[1]) ? $this->argv[1] : '';
		$ascending = isset($this->argv[2]) ? $this->argv[2] : true;
		$limit = isset($this->argv[3]) ? $this->argv[3] : '';
		
		// bb
		$columns = (empty($attributes)) ? '*' : implode($attributes,',');
		$objectName = get_class($this->sourceObject);
		
		$connection = Database::Connect();
		$sqlLimit = ($limit != '' ? "LIMIT $limit" : '');
		
		// bb
		$this->pog_query = "select $columns from `".strtolower($objectName)."` ";
		
		$list = Array();
		if (sizeof($fcv_array) > 0)
		{
			$this->pog_query .= " where ";
			for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
			{
				if (sizeof($fcv_array[$i]) == 1)
				{
					$this->pog_query .= " ".$fcv_array[$i][0]." ";
					continue;
				}
				else
				{
					if ($i > 0 && sizeof($fcv_array[$i-1]) != 1)
					{
						$this->pog_query .= " AND ";
					}
					if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
					{
						if ($GLOBALS['configuration']['db_encoding'] == 1)
						{
							$value = POG_Base::IsColumn($fcv_array[$i][2]) ? "BASE64_DECODE(".$fcv_array[$i][2].")" : "'".$fcv_array[$i][2]."'";
							$this->pog_query .= "BASE64_DECODE(`".$fcv_array[$i][0]."`) ".$fcv_array[$i][1]." ".$value;
						}
						else
						{
							$value =  POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$this->Escape($fcv_array[$i][2])."'";
							$this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
						}
					}
					else
					{
						$value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$fcv_array[$i][2]."'";
						$this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
					}
				}
			}
		}
		if ($sortBy != '')
		{
			if (isset($this->pog_attribute_type[$sortBy]['db_attributes']) && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'SET')
			{
				if ($GLOBALS['configuration']['db_encoding'] == 1)
				{
					$sortBy = "BASE64_DECODE($sortBy) ";
				}
				else
				{
					$sortBy = "$sortBy ";
				}
			}
			else
			{
				$sortBy = "$sortBy ";
			}
		}
		else
		{
			// bb
			$sortBy = $objectName.'id';
		}
		$this->pog_query .= " order by ".$sortBy." ".($ascending ? "asc" : "desc")." $sqlLimit";
	
		//bb
		$records = array();
	
		$cursor = Database::Reader($this->pog_query, $connection);
		while ($row = Database::Read($cursor))
		{
			
			//bb
			if(empty($attributes))
			{
				$records[] = ($keyValue) ? $row : array_values($row);
			}
			else
			{
				$record = array();
				foreach($attributes as $col) 
				{
					if(isset($row[$col])) 
					{
						if($keyValue)
							$record[$col] = $row[$col];
						else
							$record[] = $row[$col];
					}
				}
				$records[] = $record;
			}
		}
		return $records;
	}

	function SetupRender()
	{
		echo '<p>A memory efficient version of GetList indended to specify the order of attributes in a return, limit which attributes are returned, and/or to return only attribute values.</p>';
		echo '<p>Use the SetFilter plugin to specify returned attributes and format.</p>';
	
		if ($this->PerformUnitTest() === false)
		{
			echo get_class($this).' failed unit test';
		}
		else
		{
			echo get_class($this).' passed unit test';
		}
	}

	function AuthorPage()
	{
		return 'http://iceburg.net/';
	}

	function PerformUnitTest()
	{
		return true;
	}
}
?>